package hxy.dragon.ktor.service

import hxy.dragon.ktor.model.ExposedUser
import hxy.dragon.ktor.model.Users
import org.jetbrains.exposed.v1.core.eq
import org.jetbrains.exposed.v1.jdbc.Database
import org.jetbrains.exposed.v1.jdbc.SchemaUtils
import org.jetbrains.exposed.v1.jdbc.deleteWhere
import org.jetbrains.exposed.v1.jdbc.insert
import org.jetbrains.exposed.v1.jdbc.selectAll
import org.jetbrains.exposed.v1.jdbc.transactions.experimental.newSuspendedTransaction
import org.jetbrains.exposed.v1.jdbc.transactions.transaction
import org.jetbrains.exposed.v1.jdbc.update
import kotlinx.coroutines.Dispatchers

/**
 * 这里可以考虑改成 object
 */
class UserService(private val database: Database) {

    init {
        transaction(database) {
            SchemaUtils.create(Users)
        }
    }

//    @Suppress("DEPRECATION")
    suspend fun <T> dbQuery(block: suspend () -> T): T =
        newSuspendedTransaction(Dispatchers.IO) { block() }

    suspend fun create(user: ExposedUser): Int = dbQuery {
        Users.insert {
            it[name] = user.name
            it[age] = user.age
        }[Users.id]
    }

    suspend fun read(id: Int): ExposedUser? {
        return dbQuery {
            Users.selectAll().where { Users.id eq id }
                .map { ExposedUser(it[Users.id], it[Users.name], it[Users.age]) }
                .singleOrNull() //大于1应该报错 Too manay result
        }
    }

    suspend fun list(): List<ExposedUser> {
        return dbQuery {
            Users.selectAll()
                .map { row -> ExposedUser(row[Users.id], row[Users.name], row[Users.age]) }
        }
    }

    suspend fun update(id: Int, user: ExposedUser): Int {
        return dbQuery {
            Users.update({ Users.id eq id }) {
                it[name] = user.name
                it[age] = user.age
            }
        }
    }

    suspend fun delete(id: Int): Int {
        return dbQuery {
            Users.deleteWhere { Users.id.eq(id) }
        }
    }
}

